/**
 *
 */
package wsepForum.ui.swing.workers;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;

import javax.swing.JComponent;
import javax.swing.SwingWorker;

import wsepForum.common.elements.Section;
import wsepForum.network.client.GUIController;
import wsepForum.network.common.GUIAnswer;
import wsepForum.network.common.GUIRequest;
import wsepForum.network.common.GUIAnswer.AnswerType;
import wsepForum.network.common.GUIRequest.RequestType;
import wsepForum.ui.swing.innerPanels.AInnerPanel;
import wsepForum.ui.swing.innerPanels.SectionPanel;
import wsepForum.ui.swing.outerPanels.AOuterPanel;

/**
 * @author Amir Harel & Oren Ben-Haim
 *
 */
public abstract class ForumWorker<T extends JComponent> extends SwingWorker<T,Void> {

	protected BlockingQueue<GUIAnswer> inbox;
	protected GUIController controller;

	public ForumWorker(GUIController controller){
		this.inbox = new LinkedBlockingDeque<GUIAnswer>();
		this.controller = controller;
	}

	public void putAnswer(GUIAnswer answer){
		this.inbox.add(answer);
	}
	
	protected GUIAnswer request(GUIRequest.RequestType rType, Object[] args){
		int seq = controller.getNextSequence();
		for (int i = 0; i < 5; i++) {
			try {
				this.controller.sendRequest(new GUIRequest(rType, args ,seq), this);
				return inbox.take();	
			} catch (InterruptedException e) {
				continue;
			}
		}
		return new GUIAnswer(AnswerType.EXCEPTION,new Object[] {new InterruptedException()}, seq, 0);
	}
	
	/**
	 * @return
	 * @throws Exception
	 */
	public AInnerPanel requestHomePanel(AOuterPanel outer){
		GUIAnswer ans = request(RequestType.GET_SETCION, new Object[] {0});
		outer.setNumOfConnected(ans.getNumOfConnected());
		AInnerPanel returnedPanel = null;
		if(ans.getAnswerType().equals(AnswerType.ANSWER)){
			returnedPanel = new SectionPanel((Section) ans.getArguments()[0],(Boolean)ans.getArguments()[1],outer);
		}
		else {
			System.err.println(ans.getArguments()[0]);
		}
		return returnedPanel;
	}
}
